//
//  main.c
//  queue队列的链接存储
//
//  Created by Song on 2018/3/13.
//  Copyright © 2018年 Song. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//        typedef struct node { // 节点的结构
//            int data;
//            struct node *next;
//        }QNode, *QueuePtr;
//
//        typedef struct { // 队列的链表结构
//            QueuePtr front,rear; // 队头、队尾指针
//        }LinkQueue;

// #define int int

typedef struct QueNode{ // 节点的结构
    int value;
    struct QueNode *next;
}qNode,*qNodePtr;

typedef struct { // 队列的链表结构
    qNodePtr front;
    qNodePtr rear; // 队头、队尾指针
}LinkQueue ;

//初始化
int InitLinkQueue(LinkQueue *que){
    
    qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
    pNode = (qNodePtr)malloc(sizeof(qNode));
    pNode->next = NULL;
    que->front = que->rear = pNode; // 初始化。 队头队尾都指向 头结点
    return 0;
}

//判空
int LinkQueueEmpty(LinkQueue *que){   // 0为空 1为不空
    if(que->front == que->rear){
        printf("队列为空\n");
        return 0;
    }
    return 1;
}


//增加节点
int EnLinkQueueValue(LinkQueue *que ,int Ele){
    qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
    pNode = (qNodePtr)malloc(sizeof(qNode));
    pNode->value = Ele;
    pNode->next  = NULL;
    que->rear->next = pNode;
    que->rear = pNode;//将尾指针指向新插的节点
    
    return 0;
}

//删除节点
int DeLinkQueueValue(LinkQueue * que){
    
    int ele;
    
    int flag;
    flag = LinkQueueEmpty(que); // 0为空 1为不空
//    printf("\n ==== %d \n",flag);
    if(flag == 0){
        printf("删除节点失败\n");
        return 0;
    } else {
        //队列中存在有效的节点
        qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
        
        //将头指针指向的下一个节点地址赋给pNode节点
        pNode = que->front->next;
        ele =  pNode->value;//将要删除的节点值赋值给Ele
        
        //将头指针指向pNode的下一个位置
        que->front->next = pNode->next;
        
        if (que->rear == pNode) { // 如果队头pNode就是队尾，那么需要将 rear = front
            que->rear = que->front;
        }
        
        free(pNode);//释放内存。
        
        return ele;
        
    }
}

////删除节点
//int DeLinkQueueValue(LinkQueue * que ,int * Ele ){
//
//    int flag;
//    flag = LinkQueueEmpty(que); // 0为空 1为不空
//    printf("\n ==== %d \n",flag);
//    if(flag == 0){
//        printf("删除节点失败\n");
//        return 0;
//    } else {
//    //队列中存在有效的节点
//    qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
//
//    //将头指针指向的下一个节点地址赋给pNode节点
//    pNode = que->front->next;
//    *Ele =  pNode->value;//将要删除的节点值赋值给Ele
//
//    //将头指针指向pNode的下一个位置
//    que->front->next = pNode->next;
//    free(pNode);//释放内存。
//
//        return 0;
//
//    }
//}

//链表中节点个数
int getLinkQueueSize(LinkQueue *que){
    int size = 0;
    
    qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
    pNode = (qNodePtr)malloc(sizeof(qNode));
    
    if(LinkQueueEmpty(que)==0){
        printf("链表中不存在元素\n");
        return 0;
    }
    pNode = que->front->next;
    while(pNode){
        size ++;
        pNode = pNode->next;
    }
    free(pNode);
    return size;
}

//遍历链表数据
int showLinkQueueList(LinkQueue *que){
    
    
    if(LinkQueueEmpty(que)==0){
        printf("链表中不存在元素\n");
        return 0;
    }
    
    qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间
    pNode = (qNodePtr)malloc(sizeof(qNode));
    pNode = que->front->next;
    
    printf("节点数据为:");
    while(pNode){
        
        printf("【%d】",pNode->value);
        pNode = pNode->next;
    }
    free(pNode);
    printf("\n");
    return 0;
}

int main( void){
    int ret = 0,size=0;
    //增加节点
    int Ele1 = 1;
    int Ele2 = 2;
    int Ele3 = 3;
    
    LinkQueue *que;
    que = (LinkQueue *)malloc(sizeof(LinkQueue));
    
    //初始化
    InitLinkQueue(que);
    
    ret = EnLinkQueueValue(que ,Ele1);
    if(ret){
        printf("新增节点1失败\n");
        
    }
    ret = EnLinkQueueValue(que ,Ele2);
    if(ret){
        printf("新增节点2失败\n");
        
    }
    ret = EnLinkQueueValue(que ,Ele3);
    if(ret){
        printf("新增节点3失败\n");
        
    }
    //节点个数
    size  =  getLinkQueueSize(que);
    printf("此时的链表节点个数为【%d】\n",size);
    //遍历
    showLinkQueueList(que);
    
    //删除1个/2个节点
    int elee;
    elee = DeLinkQueueValue(que);
    elee = DeLinkQueueValue(que);
//    elee = DeLinkQueueValue(que);
//    elee = DeLinkQueueValue(que);
    
    //删除后的节点个数
    size  =  getLinkQueueSize(que);
    printf("删除后的节点个数为【%d】\n",size);
    printf("删除的节点value为【%d】\n",elee);
    
    //遍历
    showLinkQueueList(que);
    
    return 0;
    
    
}
